
#pragma once
#include <unistd.h>

#include <cstdint>
#include <iostream>
#include <list>
#include <memory>
#include <mutex>
#include <thread>
#include <vector>
#include "flv-muxer.h"
#include "flv-writer.h"

#include "CUitl.h"
#include "mongoose/mongoose.h"
#include "json/json.h"
#include "WebStream.h"

typedef struct _stflvSessionInfo {
  flv_muxer_t* m;
  std::list<std::string>* queue;
  std::mutex* mutex;
  uint32_t pts;
  char url[256];
} stflvSessionInfo;


class NetServer {
private:
  NetServer();
  ~NetServer();
  static void NSDataCB(struct mg_connection* nc, int ev, void* ev_data);

public:
  static NetServer* pNetServerInstance_;
  static NetServer* GetMng() {
    if (!pNetServerInstance_) pNetServerInstance_ = new NetServer;
    return pNetServerInstance_;
  }
  static void DestroMng() {
    if (pNetServerInstance_) {
      delete pNetServerInstance_;
      pNetServerInstance_ = 0;
    }
  }

public:
  bool Init(int port, const char* url, WebStreamCB cb);
  bool unInit();
  void SendVideoFrame(const void* data, int len, int codec);

private:
  void HttpRspJson(mg_connection* nc, Json::Value& rsq);
  void AddFlvSession(struct mg_connection* nc, struct http_message* hm);
  void CloseFlvSession(struct mg_connection* nc, struct http_message* hm);
  void FlvProcess();
  bool SendDataFlv(struct mg_connection* nc, const char* pData, int len, bool needheader = true);
  bool SendFlvHeaderTag(struct mg_connection* nc);
  flv_muxer_t* CreateFlvMuxer(void* pUsrData);
  static int OnFlvPack(void* flv, int type, const void* data, size_t bytes, uint32_t timestamp);

private:
  int m_port_;
  struct mg_mgr mgr_;
  struct mg_connection* nc_ = nullptr;
  std::thread* thread_ = nullptr;
  int hearttimes;
  bool running_ = false;
  std::mutex mutex_;

  std::string url_;
  WebStreamCB cb_;

  // FLV
  std::map<struct mg_connection*, void*> flv_conn_map_;

};
